#pragma once
#include <typescommon.h>

enum DEVICE_PARAM_RESET_LEVEL_ENUM
{
    DEVICE_PARAM_CONFIG_LEVEL_0 = 0, // level high, reset all param.
    DEVICE_PARAM_CONFIG_LEVEL_1,
    DEVICE_PARAM_CONFIG_LEVEL_2,
    DEVICE_PARAM_CONFIG_LEVEL_3,
    DEVICE_PARAM_CONFIG_LEVEL_4,
    DEVICE_PARAM_CONFIG_LEVEL_5, // defualt level
    DEVICE_PARAM_CONFIG_LEVEL_6,
    DEVICE_PARAM_CONFIG_LEVEL_7,
    DEVICE_PARAM_CONFIG_LEVEL_8,
    DEVICE_PARAM_CONFIG_LEVEL_9,
};
#define deviceParameterCommonHeadSize (sizeof(struct deviceParameterCommonHead))
#define deviceParameterDataSize(paramStruct) (sizeof(paramStruct) - deviceParameterNormalHeadSize)

#pragma pack(1)
struct deviceParameterCommonHead
{
    uint16_t paramSize;
    uint16_t paramCrc;
};
#pragma pack()

// device param size > config param size, some param can't be config
#define configOneParameterCommon(paramtype, paramName)                                                                                               \
    do                                                                                                                                               \
    {                                                                                                                                                \
        if (offsetof(paramtype, paramName) + sizeof(desParm->paramName) <= newParam->paramHead.paramSize + sizeof(struct deviceParameterCommonHead)) \
        {                                                                                                                                            \
            memcpypro(&desParm->paramName, sizeof(desParm->paramName), &newParam->paramName, sizeof(newParam->paramName));                           \
        }                                                                                                                                            \
        else                                                                                                                                         \
        {                                                                                                                                            \
            logwarn("param %s is over", #paramName);                                                                                                 \
        }                                                                                                                                            \
    } while (0);

typedef int (*deviceReadParamCall)(struct deviceParameterCommonHead *paramdata, int paramAllSize);
typedef int (*deviceWriteParamCall)(struct deviceParameterCommonHead *paramdata, int paramAllSize);
typedef int (*paramConfigCallBack)(void *outParm, const void *inputParam, int configLevel);
struct deviceParameterOperate
{
    deviceReadParamCall readcall;
    deviceWriteParamCall writecall;
    paramConfigCallBack configcall;
    struct deviceParameterCommonHead *paramdata;
    int paramAllSize;
};

int deviceParamOperateInit(struct deviceParameterOperate *parmOpt, deviceReadParamCall readfunc, deviceWriteParamCall writefunc,
                           paramConfigCallBack configfunc, struct deviceParameterCommonHead *setParam, int setParamAllSize);
int deviceParamCalculateHeadInform(struct deviceParameterCommonHead *paramData, int paramTotalSize);
int deviceParamReadFromHard(struct deviceParameterOperate *parmOpt);
int deviceParamWriteToHard(struct deviceParameterOperate *parmOpt);
int deviceParamResetAndSave(struct deviceParameterOperate *parmOpt, int configLevel);
int deviceParamOperateConfig(struct deviceParameterOperate *parmOpt, const void *inputParam, int configLevel);
